package cn.miaopasi.study.bootminio.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.miaopasi.study.bootminio.client.MinioClientTemplate;
import cn.miaopasi.study.bootminio.config.MinioConfig;
import cn.miaopasi.study.bootminio.model.R;
import io.minio.GetObjectResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Headers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * WEB API 接口.
 *
 * @author Administrator
 */
@Slf4j
@Controller
@RequestMapping("/fs")
public class MinioController {

    @Resource
    private MinioClientTemplate minioClientTemplate;
    @Resource
    private MinioConfig minioConfig;

    @PostMapping("/upload/file")
    @ResponseBody
    public R<Object> upload(@RequestParam("file") MultipartFile file) throws IOException {
        // 上传到系统配置的存储桶和目录下，文件名是原来的
        String filename = file.getOriginalFilename();
        String filePath = minioConfig.getRootPath() + "/" + filename;
        BufferedInputStream stream = IoUtil.toBuffered(file.getInputStream());
        long fileSize = file.getSize();
        String resPath = minioClientTemplate.upload(minioConfig.getBucket(), filePath, stream, fileSize);
        if (StrUtil.isNotBlank(resPath)) {
            String fileUrl = minioConfig.getEndpoint() + "/" + minioConfig.getBucket() + resPath;
            return R.ok("文件上传成功", fileUrl);
        }
        return R.fail(500, "上传失败");
    }

    @PostMapping("/upload/fileRname")
    @ResponseBody
    public R<Object> uploadTime(@RequestParam("file") MultipartFile file) throws IOException {
        // 上传到配置文件配置的存储桶和保存路径，文件名是使用Snowflake生成的，扩展名为原来的
        String fileExt = FileUtil.extName(file.getOriginalFilename());
        String filename = IdUtil.getSnowflakeNextIdStr() + "." + fileExt;
        String filePath = minioConfig.getRootPath() + "/" + filename;
        BufferedInputStream stream = IoUtil.toBuffered(file.getInputStream());
        long fileSize = file.getSize();
        String resPath = minioClientTemplate.upload(minioConfig.getBucket(), filePath, stream, fileSize);
        if (StrUtil.isNotBlank(resPath)) {
            String fileUrl = minioConfig.getEndpoint() + "/" + minioConfig.getBucket() + resPath;
            return R.ok("文件上传成功", fileUrl);
        }
        return R.fail(500, "上传失败");
    }

    @PostMapping("/download")
    public void download(@RequestParam("filePath") String filePath, HttpServletResponse response) throws IOException {
        try (ServletOutputStream stream = response.getOutputStream()) {
            String path = minioConfig.getRootPath() + "/" + filePath;
            String bucket = minioConfig.getBucket();
            String filename = FileUtil.getName(path);
            GetObjectResponse objectResponse = minioClientTemplate.getObject(bucket, filePath);
            Headers headers = objectResponse.headers();
            headers.names().forEach(name -> response.setHeader(name, headers.get(name)));
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));
            IoUtil.copy(objectResponse, stream);
            IoUtil.close(objectResponse);
        }
    }

    @PostMapping("/delete")
    @ResponseBody
    public R<Object> remove(@RequestParam("filePath") String filePath) {
        String path = minioConfig.getRootPath() + "/" + filePath;
        String bucket = minioConfig.getBucket();
        minioClientTemplate.removeObject(bucket, path);
        return R.ok("删除成功");
    }

}
